#!/bin/sh
# @author Ralf Habacker
# @brief extract dtd elements/attributes from xmllint error messages
#
useEntities=0
if test "$1" = "--use-entities"; then
    useEntities=1
    shift
fi
gawk '
BEGIN {
    useEntities = 0;
    type = " CDATA #IMPLIED"
    quote = "\047"
}

/No declaration for element/ {
    element = $11;

    if (!e[element]) {
        e[element] = 1;
        if (currentElement && (currentElement != element || _currentElement != element))
            print ">"
        print "<!ELEMENT " element " ANY >"
        print "<!ATTLIST " element
        currentElement = element
    }
}

/No declaration for attribute/ {
    attr = $11;
    _element = $14

    if (!element) {
        if (!e[_element]) {
            e[_element] = 1;
            if (_currentElement && _currentElement != _element)
                print ">"
            print "<!ATTLIST " _element
            _currentElement = _element
        }
    }

    if (!e[_element, attr]) {
        e[_element, attr] = 1;
        if (useEntities) {
            entities[attr] = 1
            print "          %" attr ";"
        } else {
            print "          " attr type
        }
    }
}

/content does not follow the DTD/ {
    print "TODO: " $0
}

END {
    if (attr)
        print ">"
    if (useEntities) {
        PROCINFO["sorted_in"] = "@ind_str_asc"
        for (entity in entities) {
            print "<!ENTITY % " entity " " quote entity type quote ">"
        }
    }
}
' useEntities=$useEntities $1
